﻿using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Packaging;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ReporterEngine
{
    public class ReportManager
    {
        public static FilesProvider Provider;

        public delegate void DelegateErrorMessage(ErrorMessageEventArgs args);
        //show ok cancel buttons
        public delegate bool DelegateRequestProblemMessage(EventArgs args);

        public delegate void DelegateAddMessageLog(MessageLogArgs args);

        public static event DelegateRequestProblemMessage OnRequestProblem;
        public static event DelegateErrorMessage OnErrorMessage;

        public static event DelegateAddMessageLog OnAddMessageLog;

        public static List<MessageLogArgs> Messages = new List<MessageLogArgs>();
        public static string DebugLog
        {
            get
            {
                StringBuilder sb = new StringBuilder();

                Messages.ForEach(x=>sb.AppendLine(x.Message));

                return sb.ToString();
            }
        }

        public void Report(ReportSettingsArgs settings)
        {
            //starting message 
            settings.AddMessageLog(new MessageLogArgs{Message = "Report started at " + DateTime.Now ,MessageLogType =  MessageLogTypes.Information});
            

            
            Provider.CopyTemplateAsResult(settings.ProjectName,settings.TemplateName,settings.ResultName);
            
            string content = null; 
            
            

            using(var stream = ReportManager.Provider.GetCif(settings.ProjectName))
            {
                using(var sr = new StreamReader(stream))
                {
                    content = sr.ReadToEnd();
                }
            }

           
            
            var cif = XDocument.Parse(content);

            var cifModel = new CIFModel();

            //set parameters from settings
            cifModel.Parameters = settings.Parameters;

            cifModel.Parse(cif);
            //model initialized


            //test only
            //cifModel.SetParameterValue("param_name", "Novitech Group");

            WordReportEngine rengine = new WordReportEngine();
            rengine.Model = cifModel;
            rengine.ReportSettings = settings;

            //open template

           // using (var package = Package.Open(settings.ResultPath, FileMode.Open))
            using(var streamresult = Provider.GetResult(settings.ProjectName,settings.ResultName, settings))
            {
                using (var package = Package.Open(streamresult, FileMode.Open))
                {
                    rengine.Package = package;

                    var replaceList = package.GetParts().ToList();

                    foreach (var part in replaceList)
                    {
                        var partPath = part.Uri.ToString();

                        using (var stream1 = part.GetStream())
                        {
                            if (partPath.EndsWith(".xml"))
                            {
                                XmlReader sr = XmlReader.Create(stream1);
                                XDocument template = XDocument.Load(sr);

                                sr.Close();
                                stream1.Close();
                                //closed stream to prevent errors during save

                                var targs = WordReportEngine.CreateArgs();

                                targs.CurrentDesign = template.Root;
                                targs.CurrentData = sQuery.New(cifModel);
                                targs.CurrentData.Elements.Add(cifModel.Notebook);

                                if (partPath.EndsWith("document.xml"))
                                {
                                    int ee = 12;
                                }

                                var validationResult = rengine.ValidateSections(template.Root.Value);

                                rengine.Report(targs);

                                //correct save changed xml word file
                                var stream = part.GetStream();

                                stream.SetLength(0);

                                TextWriter sw = new StreamWriter(stream);
                                template.Save(sw);


                                sw.Close();
                                stream.Close();

                            }
                        }
                    }
                }
                if (settings.ReportEnded != null)
                    settings.ReportEnded(this, null);
            }

            

            //starting message 

            settings.AddMessageLog(new MessageLogArgs { Message = "Report ended at " + DateTime.Now, MessageLogType = MessageLogTypes.Information });
        }

        //public static void AddMessageLog(MessageLogArgs args)
        //{
        //    Messages.Add(args);

        //    if (OnAddMessageLog != null)
        //        OnAddMessageLog(args);            
        //}

        //public static void AddMessageLog(string format, params object[] args)
        //{
        //    string result = string.Format(format, args);

        //    AddMessageLog(new MessageLogArgs { MessageLogType = MessageLogTypes.Debug, Message = result });
        //}
    }
}
